package cn.com.huzo.service.tech.impl;

import cn.com.huzo.common.util.ApplicationConfiguration;
import cn.com.huzo.model.entities.master.MaterialEntity;
import cn.com.huzo.model.entities.tech.PieceYardageHeaderEntity;
import cn.com.huzo.model.entities.tech.PieceYardageLinesEntity;
import cn.com.huzo.repository.master.MaterialRepository;
import cn.com.huzo.repository.tech.PieceYardageHeaderRepository;
import cn.com.huzo.repository.tech.PieceYardageLinesColourSchemaRepository;
import cn.com.huzo.repository.tech.PieceYardageLinesProductColourRepository;
import cn.com.huzo.repository.tech.PieceYardageLinesProductSizeRepository;
import cn.com.huzo.repository.tech.PieceYardageLinesRepository;
import cn.com.huzo.repository.tech.PieceYardageLinesSizeGradeRepository;
import cn.com.huzo.service.tech.PieceYardageLinesManager;
import huzofw.service.impl.GenericManagerImpl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 单耗明细管理服务对象类实现。
 *
 * @author 吴旭
 */
@Service("PieceYardageLinesManager")
public class PieceYardageLinesManagerImpl extends GenericManagerImpl<PieceYardageLinesEntity, String>
        implements PieceYardageLinesManager {

    private final String rootNodeText = (String) ApplicationConfiguration.getProperty("Catalogue_PieceYardage");

    @Resource(name = "PieceYardageHeaderRepository")
    private PieceYardageHeaderRepository _dao;

    @Resource(name = "PieceYardageLinesRepository")
    private PieceYardageLinesRepository _dao_lines;

    @Resource(name = "PieceYardageLinesProductColourRepository")
    private PieceYardageLinesProductColourRepository _dao_lines_product_colour;

    @Resource(name = "PieceYardageLinesColourSchemaRepository")
    private PieceYardageLinesColourSchemaRepository _dao_lines_colour_schema;

    @Resource(name = "PieceYardageLinesProductSizeRepository")
    private PieceYardageLinesProductSizeRepository _dao_lines_product_size;

    @Resource(name = "PieceYardageLinesSizeGradeRepository")
    private PieceYardageLinesSizeGradeRepository _dao_lines_size_grade;

    @Resource(name = "MaterialRepository")
    private MaterialRepository _dao_material;

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Override
    public List<PieceYardageLinesEntity> fetchLinesByHeaderKey(Long headerId) throws Exception {
        return _dao_lines.fetchByHeaderKey(headerId);
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Transactional
    @Override
    public List<PieceYardageLinesEntity> insertLines(List<PieceYardageLinesEntity> itemList) throws Exception {
        // step1：插入数据
        Integer rowsAffected = _dao_lines.batchInsert(itemList);
        // step2：重设顺序号
        _dao_lines.resetLinesOrder(itemList.get(0).getHeaderId());
        // step3：审计日志
        if (rowsAffected > 0) {
            // 更新相关主记录的最后操作时间，便于排序
            _dao.updateLastUpdatedDate(itemList.get(0).getHeaderId());
            // 记录日志
            PieceYardageHeaderEntity _header = _dao.fetchByKey(rootNodeText, itemList.get(0).getHeaderId());
            writeAuditLog(itemList.get(0).getUpdatedBy(), "技术管理→单耗明细",
                    "款号：" + _header.getStyleNo(),
                    "增加明细");
        }

        // 返回插入后的数据
        return _dao_lines.fetchByHeaderKey(itemList.get(0).getHeaderId());
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Transactional
    @Override
    public Map<String, Object> updateLines(List<PieceYardageLinesEntity> itemList) throws Exception {
        Map<String, Object> _result = new HashMap();
        List<Integer> _err_rowno = new ArrayList();

        // 每个行都要判断料号，如果有错误就把行号保存到_err_rowno
        for (int i = 0; i < itemList.size(); i++) {
            if (itemList.get(i).getPoQuotedFlag() == false) {
                if (_dao_lines.updateLinesByMaterialId(itemList.get(i).getLinesId(), itemList.get(i).getMaterialId()) <= 0) {
                    // 如果没有料号的改变，则不做错误记录，否则记录下当前的行号
                    if (itemList.get(i).getMaterialCode() != null) {
                        _err_rowno.add(itemList.get(i).getOrderNo());
                    }
                }
            }
        }

        // 如果料号没有错误，更新数据，否则就返回错误的行号，做配色方案
        if (_err_rowno.isEmpty()) {
            Integer rowsAffected = _dao_lines.batchUpdate(itemList);
            // 做配色方案
            itemList.stream().forEach((instance) -> {
                // 根据单耗表明细标识删除配色方案
                _dao_lines_colour_schema.deleteByParentLinesKey(instance.getLinesId());
                // 插入配色方案
                if (instance.getColourSchemaList() != null && !instance.getColourSchemaList().isEmpty()) {
                    _dao_lines_colour_schema.insert(instance.getColourSchemaList());
                }
            });
            if (rowsAffected > 0) {
                // 更新相关主记录的最后操作时间，便于排序
                _dao.updateLastUpdatedDate(itemList.get(0).getHeaderId());
                // 记录日志
                PieceYardageHeaderEntity _header = _dao.fetchByKey(rootNodeText, itemList.get(0).getHeaderId());
                writeAuditLog(itemList.get(0).getUpdatedBy(), "技术管理→单耗明细",
                        "款号：" + _header.getStyleNo(),
                        "更新明细");
            }

            _result.put("Success", true);
            _result.put("LinesList", _dao_lines.fetchByHeaderKey(itemList.get(0).getHeaderId()));
        } else {
            _result.put("Success", false);
            _result.put("ErrRowNo", _err_rowno);
        }

        return _result;
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Transactional
    @Override
    public Map<String, Object> updateLinesByMaterialId(Long headerId, String linesId, Long materialId, Long updatedBy) throws Exception {
        Map<String, Object> _result = new HashMap();
        if (_dao_lines.updateLinesByMaterialId(linesId, materialId) > 0) {
            // 更新相关主记录的最后操作时间，便于排序
            _dao.updateLastUpdatedDate(headerId);

            // 记录日志
            PieceYardageHeaderEntity _header = _dao.fetchByKey(rootNodeText, headerId);
            writeAuditLog(updatedBy, "技术管理→单耗明细",
                    "款号：" + _header.getStyleNo() + "　料号：" + materialId,
                    "更新明细材料");

            MaterialEntity entity = _dao_material.fetchByMaterialId(materialId);
            _result.put("Success", true);
            _result.put("MaterialId", entity.getMaterialId());
            _result.put("MaterialName", entity.getMaterialName());
            _result.put("MaterialCode", entity.getMaterialCode());
            _result.put("Specification", entity.getSpecification());
            _result.put("SupplierName", entity.getSupplierName());
            _result.put("UomId", entity.getUomId());
            _result.put("UomName", entity.getUomName());
        } else {
            _result.put("Success", false);
        }
        return _result;
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Transactional
    @Override
    public Map<String, Object> delete(Map<String, Object> criterion) throws Exception {
        Map<String, Object> _result = new HashMap();

        // step1：删除
        Integer rowsAffected = _dao_lines.delete(MapUtils.getString(criterion, "LinesId"));
        if (rowsAffected > 0) {
            // step2：重设行号
            _dao_lines.resetLinesOrder(MapUtils.getLong(criterion, "HeaderId"));
            // 更新相关主记录的最后操作时间，便于排序
            _dao.updateLastUpdatedDate(MapUtils.getLong(criterion, "HeaderId"));
            // step3：审计日志
            writeAuditLog(MapUtils.getLong(criterion, "DeletedBy"),
                    "技术管理→单耗明细",
                    "明细数据（" + MapUtils.getString(criterion, "LinesData") + "）",
                    "删除明细");
        }
        _result.put("LinesList", _dao_lines.fetchByHeaderKey(MapUtils.getLong(criterion, "HeaderId")));

        return _result;
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Transactional
    @Override
    public List<PieceYardageLinesEntity> batchDeleteLines(List<PieceYardageLinesEntity> itemList) throws Exception {
        // step1：删除
        Integer rowsAffected = _dao_lines.batchDelete(itemList);
        // step2：重设行号
        _dao_lines.resetLinesOrder(itemList.get(0).getHeaderId());
        // step3：审计日志
        if (rowsAffected > 0) {
            // 更新相关主记录的最后操作时间，便于排序
            _dao.updateLastUpdatedDate(itemList.get(0).getHeaderId());
            // 记录日志
            PieceYardageHeaderEntity _header = _dao.fetchByKey(rootNodeText, itemList.get(0).getHeaderId());
            writeAuditLog(itemList.get(0).getDeletedBy(), "技术管理→单耗明细",
                    "款号：" + _header.getStyleNo(),
                    "批量删除明细");
        }

        return _dao_lines.fetchByHeaderKey(itemList.get(0).getHeaderId());
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Transactional
    @Override
    public List<PieceYardageLinesEntity> batchClearLinesPieceYardage(List<PieceYardageLinesEntity> itemList) throws Exception {
        Integer rowsAffected = _dao_lines.batchClearLinesPieceYardage(itemList);
        if (rowsAffected > 0) {
            // 更新单耗员
            PieceYardageHeaderEntity _instance = new PieceYardageHeaderEntity();
            _instance.setHeaderId(itemList.get(0).getHeaderId());
            _instance.setGradedBy(itemList.get(0).getUpdatedBy());
            _dao.updateGradedBy(_instance);
            // 更新相关主记录的最后操作时间，便于排序
            _dao.updateLastUpdatedDate(itemList.get(0).getHeaderId());
            // 记录日志
            PieceYardageHeaderEntity _header = _dao.fetchByKey(rootNodeText, itemList.get(0).getHeaderId());
            writeAuditLog(itemList.get(0).getUpdatedBy(), "技术管理→单耗明细",
                    "款号：" + _header.getStyleNo(),
                    "清空单耗");
        }
        return _dao_lines.fetchByHeaderKey(itemList.get(0).getHeaderId());
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Transactional
    @Override
    public List<PieceYardageLinesEntity> batchClearLinesSizePieceYardage(List<PieceYardageLinesEntity> itemList) throws Exception {
        Integer rowsAffected = _dao_lines_size_grade.batchClearLinesSizePieceYardage(itemList);
        if (rowsAffected > 0) {
            // 更新单耗员
            PieceYardageHeaderEntity _instance = new PieceYardageHeaderEntity();
            _instance.setHeaderId(itemList.get(0).getHeaderId());
            _instance.setGradedBy(itemList.get(0).getUpdatedBy());
            _dao.updateGradedBy(_instance);
            // 更新相关主记录的最后操作时间，便于排序
            _dao.updateLastUpdatedDate(itemList.get(0).getHeaderId());
            // 记录日志
            PieceYardageHeaderEntity _header = _dao.fetchByKey(rootNodeText, itemList.get(0).getHeaderId());
            writeAuditLog(itemList.get(0).getUpdatedBy(), "技术管理→单耗明细",
                    "款号：" + _header.getStyleNo(),
                    "清空单耗");
        }
        return _dao_lines.fetchByHeaderKey(itemList.get(0).getHeaderId());
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Transactional
    @Override
    public Map<String, Object> updateLinesGrade(List<PieceYardageLinesEntity> itemList) throws Exception {
        Map<String, Object> _result = new HashMap();

        Integer rowsAffected = _dao_lines.updateLinesGrade(itemList);
        if (rowsAffected > 0) {
            // 更新单耗员
            PieceYardageHeaderEntity _instance = new PieceYardageHeaderEntity();
            _instance.setHeaderId(itemList.get(0).getHeaderId());
            _instance.setGradedBy(itemList.get(0).getUpdatedBy());
            _dao.updateGradedBy(_instance);
            // 更新相关主记录的最后操作时间，便于排序
            _dao.updateLastUpdatedDate(itemList.get(0).getHeaderId());
            // 记录日志
            PieceYardageHeaderEntity _header = _dao.fetchByKey(rootNodeText, itemList.get(0).getHeaderId());
            writeAuditLog(itemList.get(0).getUpdatedBy(), "技术管理→单耗明细",
                    "款号：" + _header.getStyleNo(),
                    "更新单耗");

            _result.put("Success", true);
            _result.put("LinesList", _dao_lines.fetchByHeaderKey(itemList.get(0).getHeaderId()));
        } else {
            _result.put("Success", false);
        }

        return _result;
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Transactional
    @Override
    public Map<String, Object> updateLinesSizeGrade(List<PieceYardageLinesEntity> itemList) throws Exception {
        Map<String, Object> _result = new HashMap();
        // Step 1: 清空选定行的尺码单耗
        _dao_lines_size_grade.batchClearLinesSizePieceYardage(itemList);
        // Step 2: 尺码单耗
        itemList.stream().forEach((instance) -> {
            // 插入尺码单耗
            if (instance.getSizeGradeList() != null && !instance.getSizeGradeList().isEmpty()) {
                _dao_lines_size_grade.insert(instance.getSizeGradeList());
            }
        });

        // 更新单耗员
        PieceYardageHeaderEntity _instance = new PieceYardageHeaderEntity();
        _instance.setHeaderId(itemList.get(0).getHeaderId());
        _instance.setGradedBy(itemList.get(0).getUpdatedBy());
        _dao.updateGradedBy(_instance);
        // 更新相关主记录的最后操作时间，便于排序
        _dao.updateLastUpdatedDate(itemList.get(0).getHeaderId());

        // 记录日志
        PieceYardageHeaderEntity _header = _dao.fetchByKey(rootNodeText, itemList.get(0).getHeaderId());
        writeAuditLog(itemList.get(0).getUpdatedBy(), "技术管理→全码单耗明细",
                "款号：" + _header.getStyleNo(),
                "更新单耗");

        _result.put("Success", true);
        _result.put("LinesList", _dao_lines.fetchByHeaderKey(itemList.get(0).getHeaderId()));

        return _result;
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Transactional
    @Override
    public List<PieceYardageLinesEntity> insertFromClipboard(Long headerId, String copiedLinesId, Long materialId,
            Long uomId, String specification, Integer orderNo, Long createdBy, Long updatedBy) throws Exception {
        // 粘贴数据
        _dao_lines.insertFromClipboard(headerId, copiedLinesId, materialId,
                uomId, specification, orderNo, createdBy, updatedBy);
        // 重设顺序号
        _dao_lines.resetLinesOrder(headerId);
        // 粘贴相应的配色方案并设置和明细的对应关系
        _dao_lines_colour_schema.insertLinesFromClipboard(headerId, copiedLinesId);
        // 粘贴相应的尺码单耗以及和明细的对应关系
        _dao_lines_size_grade.insertLinesFromClipboard(headerId, copiedLinesId);
        // 更新相关主记录的最后操作时间，便于排序
        _dao.updateLastUpdatedDate(headerId);

        // 返回插入后的数据
        return _dao_lines.fetchByHeaderKey(headerId);
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Transactional
    @Override
    public Map<String, Object> importLinesFromOtherBom(Long headerId, Long importedBomHeaderId,
            Long createdBy, Long updatedBy) throws Exception {
        Map<String, Object> _result = new HashMap();
        // 插入数据
        Integer rowsAffected = _dao_lines.importLinesFromOtherBom(headerId, importedBomHeaderId, createdBy, updatedBy);
        if (rowsAffected > 0) {
            // 重设顺序号
            _dao_lines.resetLinesOrder(headerId);
            // 引入相应的产品颜色
            //_dao_lines_product_colour.importLinesFromOtherBom(headerId, importedBomHeaderId);
            // 引入相应的配色方案并重新设置和明细的对应关系
            //_dao_lines_colour_schema.importLinesFromOtherBom(headerId, importedBomHeaderId);
            //_dao_lines_colour_schema.updateParentLinesIdForImportedLines(headerId);
            // 引入相应的产品尺码
            _dao_lines_product_size.importLinesFromOtherBom(headerId, importedBomHeaderId);
            // 引入相应的配色方案并重新设置和明细的对应关系
            _dao_lines_size_grade.importLinesFromOtherBom(headerId, importedBomHeaderId);
            _dao_lines_size_grade.updateParentLinesIdForImportedLines(headerId);
            // 将引入的单耗明细ID字段清空
            _dao_lines.clearImportedBomLinesId(headerId);
            // 更新相关主记录的最后操作时间，便于排序
            _dao.updateLastUpdatedDate(headerId);
            // 记录日志
            PieceYardageHeaderEntity _header = _dao.fetchByKey(null, headerId);
            writeAuditLog(updatedBy, "技术管理→单耗明细",
                    "款号：" + _header.getStyleNo(),
                    "引入单耗");
        }

        // 返回插入后的全部数据
        _result.put("ProductColourNode", _dao_lines_product_colour.fetchByHeaderKey(headerId));
        _result.put("LinesList", _dao_lines.fetchByHeaderKey(headerId));

        return _result;
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Transactional
    @Override
    public Map<String, Object> updateLinesOrder(List<PieceYardageLinesEntity> itemList) throws Exception {
        Map<String, Object> _result = new HashMap();
        Integer rowsAffected = _dao_lines.updateLinesOrder(itemList);
        if (rowsAffected > 0) {
            _result.put("Success", true);
        } else {
            _result.put("Success", false);
        }
        _result.put("LinesList", _dao_lines.fetchByHeaderKey(itemList.get(0).getHeaderId()));

        return _result;
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Transactional
    @Override
    public List<PieceYardageLinesEntity> batchChangeMaterialColour(List<Map<String, Object>> itemList) throws Exception {
        Integer rowsAffected = 0;
        // 根据成品色，改变选定的材料的配色
        for (int i = 0; i < itemList.size(); i++) {
            Map<String, Object> item = itemList.get(i);
            rowsAffected = _dao_lines_colour_schema.changeMaterialColour(
                    MapUtils.getLong(item, "HeaderId"),
                    MapUtils.getString(item, "ParentLinesId"),
                    MapUtils.getString(item, "MaterialColourName"),
                    MapUtils.getLong(item, "ProductColourId")) + 1;
        }
        if (rowsAffected > 0) {
            writeAuditLog(MapUtils.getLong(itemList.get(0), "UpdatedBy"), "技术管理→单耗明细",
                    "款号：" + MapUtils.getString(itemList.get(0), "StyleNo")
                    + "  对应成品色：" + MapUtils.getString(itemList.get(0), "ProductColourName"),
                    "更改材料色");
        }

        // 返回插入后的全部数据
        return _dao_lines.fetchByHeaderKey(MapUtils.getLong(itemList.get(0), "HeaderId"));
    }
}
